/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.rpc.workflow.user;

import com.je.common.base.DynaBean;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.SecurityUserHolder;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.rpc.workflow.user.special.SpecialUserParserEnum;
import com.je.rbac.rpc.workflow.user.special.SpecialUserParserFactory;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 人员树
 */
public class ParserUserJsonTreeFilter extends FilterChain implements Filter {

    @Override
    public void handler(ParserUserBo parserUserBo, JSONTreeNode jsonTreeNode , FilterChain filterChain) {
        List<String> types = parserUserBo.getTypes();
        //选择类型不为空
        if (types != null && types.size() > 0) {
            //先获取，选项中的所有人员
            //去重
            //看树上有没有这些人员信息，找出没有的人员信息

            //看树上有没有构建公司，有的话构建公司人员信息
            //看人员所属部门在不在树上，在的话 直接add
            //看人员所属公司在不在树上，在的话 构建部门人员 在公司下 add


            //看树上有没有构建部门并且没有构建公司，有的话构建部门人员信息
            //看人员所属部门在不在树上，在的话 直接add

            //都没有的话只构建人员信息
            List<DynaBean> users = new ArrayList<>();
            //当前登录人
            if (types.contains(SpecialUserParserEnum.LOGINED_USER.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.LOGINED_USER.toString())
                        .getUserInfo(parserUserBo.getUserId(), parserUserBo.getAddOwn());

                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }

            }
            //直接领导
            if (types.contains(SpecialUserParserEnum.DIRECT_LEADER.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.DIRECT_LEADER.toString())
                        .getUserInfo(parserUserBo.getUserId(), parserUserBo.getAddOwn());

                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }

            }
            //部门领导
            if (types.contains(SpecialUserParserEnum.DEPT_LEADER.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.DEPT_LEADER.toString())
                        .getUserInfo(parserUserBo.getUserId(), parserUserBo.getAddOwn());
                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }
            }
            //监管部门领导
            if (types.contains(SpecialUserParserEnum.DEPT_MONITOR_LEADER.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.DEPT_MONITOR_LEADER.toString())
                        .getUserInfo(parserUserBo.getUserId(), parserUserBo.getAddOwn());
                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }
            }
            //流程启动人
            if (types.contains(SpecialUserParserEnum.STARTER_USER.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.STARTER_USER.toString())
                        .getUserInfo(parserUserBo.getStarterUser(), parserUserBo.getAddOwn());
                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }
            }
            //指派人
            if (types.contains(SpecialUserParserEnum.TASK_ASSGINE.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.TASK_ASSGINE.toString())
                        .getUserInfo(parserUserBo.getTaskAssigner(), parserUserBo.getAddOwn());
                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }
            }
            //指派人直属领导
            if (types.contains(SpecialUserParserEnum.TASK_ASSGINE_HEAD.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.TASK_ASSGINE_HEAD.toString())
                        .getUserInfo(parserUserBo.getTaskAssigner(), parserUserBo.getAddOwn());
                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }
            }
            //前置任务指派人
            if (types.contains(SpecialUserParserEnum.PREV_ASSIGN_USER.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.PREV_ASSIGN_USER.toString())
                        .getUserInfo(parserUserBo.getFrontTaskAssigner(), parserUserBo.getAddOwn());
                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }
            }
            //前置任务指派人直接领导
            if (types.contains(SpecialUserParserEnum.PREV_ASSIGN_USER_DIRECT_LEADER.toString())) {
                List<DynaBean> userInfo = SpecialUserParserFactory.getParserByCode(SpecialUserParserEnum.PREV_ASSIGN_USER_DIRECT_LEADER.toString())
                        .getUserInfo(parserUserBo.getFrontTaskAssigner(), parserUserBo.getAddOwn());
                if (null != userInfo && userInfo.size() > 0) {
                    users.addAll(userInfo);
                }
            }
            //去重

            List<String> accountDeptIds = users.stream()
                    .map(bean -> bean.getStr("JE_RBAC_ACCOUNTDEPT_ID"))
                    .distinct()
                    .collect(Collectors.toList());

            //看树上有没有这些人员信息，找出没有的人员信息
            List<String> otherUserIds = new ArrayList<>();
            for (String accountDeptId : accountDeptIds) {
                if (JsonTreeContext.getJsonTree(accountDeptId) == null) {
                    otherUserIds.add(accountDeptId);
                }
            }
//            List<DynaBean> otherUserBeans = userBeans.stream()
//                    .filter(bean -> otherUserIds.contains(bean.getStr("JE_RBAC_ACCOUNTDEPT_ID")))
//                    .collect(Collectors.toList());
            //树上都有这些人员信息的话 不用构建了
            if (otherUserIds.size() == 0) {
                return;
            }
            List<DynaBean> otherUserBeans = metaService.select("JE_RBAC_VACCOUNTDEPT",ConditionsWrapper.builder().in("JE_RBAC_ACCOUNTDEPT_ID",otherUserIds));

            //根据部门id分组
            Map<String, List<DynaBean>> deptListMap = otherUserBeans.stream().collect(Collectors.groupingBy(bean -> bean.getStr("ACCOUNTDEPT_DEPT_ID")));

            DynaBean table = beanService.getResourceTable("JE_RBAC_DEPARTMENT");
            List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
            JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);

            if (parserUserBo.getCompanyDeptUserTree() || parserUserBo.getCompanyUserTree()) {
                //看树上有没有构建公司，有的话构建公司人员信息

                //看人员所属部门在不在树上，在的话 直接add
                //不在的话 ， 查找部门所属公司，在不在树上，不在的话 并构建公司部门人员信息
                //不在的话 ， 看人员所属公司在不在树上，在的话 构建部门人员 在公司下 add
                checkCompany(deptListMap, parserUserBo.getMultiple());

            } else if (parserUserBo.getDeptUserTree() && (!parserUserBo.getCompanyDeptUserTree() && !parserUserBo.getCompanyUserTree())) {
                //看树上有没有构建部门并且没有构建公司，有的话构建部门人员信息

                //看人员所属部门在不在树上，在的话 直接add
                //不在的话构建部门人员信息

                //所在部门
                Set<String> deptIds = deptListMap.keySet();
                for (String deptId : deptIds) {
                    //部门信息
                    DynaBean deptBean = metaService.selectOne("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder().in("JE_RBAC_DEPARTMENT_ID", deptId));
                    //部门下人员信息
                    List<DynaBean> accountDeptBeanList = deptListMap.get(deptId);
                    if (!parserUserBo.getAddOwn()) {
                        accountDeptBeanList = deptListMap.get(deptId).stream().filter(x -> !(x.getStr("JE_RBAC_ACCOUNTDEPT_ID")
                                .equals(SecurityUserHolder.getCurrentAccount().getDeptId()))).collect(Collectors.toList());
                    }
                    if (null == JsonTreeContext.getJsonTree(deptId)) {
                        //构建父部门树
                        JSONTreeNode parentNode = buildDeptTreeNode(template, JsonTreeContext.getJsonTree("ROOT").getId(), deptBean);
                        //节点信息类型
                        parentNode.setNodeInfo("department");
                        parentNode.setNodeInfoType("department");
                        JsonTreeContext.putJsonTree(parentNode.getId(), parentNode);
                        JsonTreeContext.getJsonTree("ROOT").getChildren().add(parentNode);

                        //构建人员信息
                        if (accountDeptBeanList != null && accountDeptBeanList.size() > 0) {
                            for (DynaBean eachAccountDeptBean : accountDeptBeanList) {
                                if (parentNode.getBean().get("JE_RBAC_DEPARTMENT_ID").equals(eachAccountDeptBean.getStr("ACCOUNTDEPT_DEPT_ID"))) {
                                    //构建当前部门下人员信息
                                    parseAccountDepartmentToTree(parentNode, eachAccountDeptBean, parserUserBo.getMultiple(), true);
                                }
                            }
                        }
                    } else {
                        JSONTreeNode deptTreeNode = JsonTreeContext.getJsonTree(deptId);
                        //构建人员信息
                        if (accountDeptBeanList != null && accountDeptBeanList.size() > 0) {
                            for (DynaBean eachAccoutDeptBean : accountDeptBeanList) {
                                if (deptTreeNode.getBean().get("JE_RBAC_DEPARTMENT_ID").equals(eachAccoutDeptBean.getStr("ACCOUNTDEPT_DEPT_ID"))) {
                                    //构建当前部门下人员信息
                                    parseAccountDepartmentToTree(deptTreeNode, eachAccoutDeptBean, parserUserBo.getMultiple(), true);
                                }
                            }
                        }
                    }

                }
            } else if (!parserUserBo.getDeptUserTree() && (!parserUserBo.getCompanyDeptUserTree() && !parserUserBo.getCompanyUserTree())) {
                //都没有的话只构建人员信息
                JSONTreeNode rootTreeNode = JsonTreeContext.getJsonTree("ROOT");
                //构建人员信息
                if (otherUserBeans.size() > 0) {
                    for (DynaBean eachAccoutDeptBean : otherUserBeans) {
                        parseAccountDepartmentToTree(rootTreeNode, eachAccoutDeptBean, parserUserBo.getMultiple(), true);
                    }
                }

            }
        }
    }
}
